﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using MahApps.Metro.Controls;
using Shoozla.DataModel;
using System.Windows.Threading;

namespace Shoozla.ViewModel
{

    class ProgressBarViewModel : ViewModelBase
    {
        #region Properties
        private List<IProgressOperation> _workQueue;  

        public Window View { get; set; }
        public String Description { get; set; }
        public double Maximum { get; set; }
        public double Minimum { get; set; }
        public double Current { get; set; }
        public bool ShowBar { get; set; }

        #endregion

        public ProgressBarViewModel(Window view, Window owner) : base (view,owner)
        {
            Maximum = 100;
            Minimum = 0;
            Current = 0;
            ShowBar = false;
            _workQueue = new List<IProgressOperation>();                 
        }
       
        #region commands
        private RelayCommand _CmdCancel;
        public RelayCommand CmdCancel
        {
            get
            {
                if (_CmdCancel == null)
                {
                    _CmdCancel = new RelayCommand(param => DoCmdCancel(), (c) =>
                    {
                        if (AppModel.IsAppWorking)
                            return true;
                        else
                            return false;
                    });
                }
                return _CmdCancel;
            }
        }
        #endregion

        #region Do commands
        private void DoCmdCancel()
        {
            if (AppModel.IsAppWorking)
            {
                var res = MetroMessageBox.MetroShow("","Do you really want to stop the operation?",true,App.MainView,MessageIcon.Info,true);
                if (res == MessageBoxResult.OK)
                {
                    AppModel.StopAllWork();
                    OnRequestClose();
                }

            }
        }
        #endregion

        public void AddWork(List<IProgressOperation> operations)
        {

            _workQueue = operations;

            foreach (IProgressOperation op in _workQueue)
            {

                op.ProgressChanged += new EventHandler<ProgressOperationEventArgs>(newProgressOperation_ProgressChanged);
                op.Started += new EventHandler<ProgressOperationEventArgs>(newProgressOperation_Started);
                op.Completed += new EventHandler<ProgressOperationEventArgs>(newProgressOperation_Completed);
                Maximum += (double)op.Maximum; //max == the grand total sum
                op.Start();
            }

            OnPropertyChanged("Maximum");
            OnPropertyChanged("Minimum");
            OnPropertyChanged("Current");
        }

        void newProgressOperation_Completed(object sender, ProgressOperationEventArgs e)
        {
            ((IProgressOperation) sender).ProgressChanged -= newProgressOperation_ProgressChanged;
            ((IProgressOperation)sender).Started -= newProgressOperation_Started;
            ((IProgressOperation)sender).Completed -= newProgressOperation_Completed;

            //an operation finished, i need to check if there is other work to do
            DispatcherUIThread.BeginInvoke((Action)(() =>
            {
                _workQueue.Remove((IProgressOperation)sender);
                if (_workQueue.Count == 0)
                    OnRequestClose();
            }));

        }

        void newProgressOperation_Started(object sender, ProgressOperationEventArgs e)
        {
        //    DispatcherUIThread.BeginInvoke((Action)(() =>
        //    {

        //        ; ;

        //    }));
        }

        void newProgressOperation_ProgressChanged(object sender, ProgressOperationEventArgs e)
        {
            DispatcherUIThread.Invoke((Action)(() =>
            {
                Description = e.Message;
                Maximum = e.Maximum;
                Current = e.Current;
                
                OnPropertyChanged("Description");
                OnPropertyChanged("Maximum");
                OnPropertyChanged("Current");
            }));
        }
    }
}
